package icu.yougan.trade.utils;

import icu.yougan.trade.service.UserService;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class JwtTokenUtil {

    @Value("${jwt.secret}")
    private String secret;

    @Value("${jwt.expiration}")
    private Long expiration; // 过期时间（毫秒）
    @Autowired
    private UserService userService;
    // 生成签名密钥
    private SecretKey getSigningKey() {
        // 注意：这里使用HMAC-SHA算法，确保secret长度足够
        return Keys.hmacShaKeyFor(secret.getBytes());
    }
    /** 生成Token */
    public String generateToken(UserDetails userDetails) {
        return generateToken(userDetails, null);
    }

    // 重载方法：新增角色参数
    public String generateToken(UserDetails userDetails, String role) {
        // 基础用户信息
        icu.yougan.trade.entity.User user = userService.getUserByAccountNum(userDetails.getUsername());
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", user.getId());

        // 如果有传入角色则添加，否则从UserDetails获取
        if(role != null) {
            claims.put("roles", role);
        } else {
            // 从Spring Security的权限中提取角色
            Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();
            if(authorities != null && !authorities.isEmpty()) {
                claims.put("roles", authorities.stream()
                        .map(GrantedAuthority::getAuthority)
                        .collect(Collectors.toList()));
            }
        }

        return Jwts.builder()
                .setClaims(claims)
                .setSubject(userDetails.getUsername())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + expiration))
                .signWith(getSigningKey())
                .compact();
    }


    // 工具类方法：从Token中解析用户ID
    public Long getUserIdFromToken(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(getSigningKey())
                .build()
                .parseClaimsJws(token.replace("Bearer ", ""))
                .getBody();
        return claims.get("userId", Long.class);
    }
    /** 从Token中解析用户名 */
    public String getUsernameFromToken(String token) {
        return Jwts.parser()
                .setSigningKey(getSigningKey())
                .build()
                .parseClaimsJws(token)
                .getBody()
                .getSubject();
    }
    /**
     * 解析Token并返回Authentication对象
     */
    public Authentication parseToken(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(getSigningKey())
                .build()
                .parseClaimsJws(token)
                .getBody();

        // 假设您的用户实体实现了UserDetails
        UserDetails userDetails = new org.springframework.security.core.userdetails.User(
                claims.getSubject(),
                "", // 密码不需要
                Collections.emptyList() // 权限列表
        );

        return new UsernamePasswordAuthenticationToken(
                userDetails,
                null,
                userDetails.getAuthorities()
        );
    }

    /**
     * 私聊时获取Jwt令牌
     * @param token
     * @return
     */
    public Authentication getAuthentication(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(getSigningKey())
                .build()
                .parseClaimsJws(token)
                .getBody();

        UserDetails userDetails = new org.springframework.security.core.userdetails.User(
                claims.getSubject(),
                "",
                Collections.emptyList() // 根据实际情况添加权限
        );

        return new UsernamePasswordAuthenticationToken(
                userDetails,
                null,
                userDetails.getAuthorities()
        );
    }
    /** 验证Token有效性 */
    public boolean validateToken(String token, UserDetails userDetails) {
        final String username = getUsernameFromToken(token);
        return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
    }

    /** 检查Token是否过期 */
    private Boolean isTokenExpired(String token) {
        final Date expiration = getExpirationDateFromToken(token);
        return expiration.before(new Date());
    }

    /** 获取过期时间 */
    public Date getExpirationDateFromToken(String token) {
        return Jwts.parser()
                .setSigningKey(getSigningKey())
                .build()
                .parseClaimsJws(token)
                .getBody()
                .getExpiration();
    }
}